#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
day 36 homework
"""
# 线程部分：读程序
# 1、程序从flag a执行到falg b的时间大致是多少秒？
"""
几乎同时
"""

# 2、程序从flag a执行到falg b的时间大致是多少秒？
"""
几乎同时
"""

# 3、程序从flag a执行到falg b的时间大致是多少秒？
"""
60s
"""

# 4、读程序，请确认执行到最后number是否一定为0
"""
False
"""

# 5、读程序，请确认执行到最后number是否一定为0
"""
True
"""

# 7、读程序，请确认执行到最后number的长度是否一定为1
"""
False
"""

# 8、读程序，请确认执行到最后number的长度是否一定为1
"""
False
"""
# 协程
# 1、什么是协程？常用的协程模块有哪些？
"""
能够在一个线程下的多个任务之间来回切换，那么每一个任务都是一个协程
 greenlet gevent
"""
# 2、协程中的join是用来做什么用的？它是如何发挥作用的？
"""
join阻塞，等待任务结束。
因为协程任务时遇到阻塞时才执行，所以可以利用join来执行协程任务。如果没有阻塞协程任务则不执行。
"""
# 3、使用协程实现并发的tcp server端
"""
import gevent
import socket
from gevent import monkey
monkey.patch_all()
def run(conn):
    while True:
        msg = conn.recv(1024).decode('utf-8')
        conn.send(msg.upper().encode('utf-8'))


if __name__ == '__main__':
    sk = socket.socket()
    sk.bind(('127.0.0.1', 9000))
    sk.listen()
    while True:
        conn, addr = sk.accept()
        g = gevent.spawn(run, conn)
"""

# 4、在一个列表中有多个url，请使用协程访问所有url，将对应的网页内容写入文件保存
"""
from gevent import monkey
monkey.patch_all()
import requests
import gevent

url_lst = [
        'https://www.baidu.com',
        'http://www.cnblogs.com',
        'http://www.douban.com',
        'http://www.tencent.com',
        'http://www.cnblogs.com/Eva-J/articles/8306047.html',
        'http://www.cnblogs.com/Eva-J/articles/7206498.html',
    ]
def run(url):
    ret = requests.get(url)
    print(ret)
    ret = ret.text
    with open('a.txt','a',encoding='utf-8') as f:
        f.write(ret)

if __name__ == '__main__':
    g_l = list()
    for url in url_lst:
        print(url)
        g = gevent.spawn(run, url)
        g_l.append(g)
    for g in g_l:
        g.join()
"""
# 综合
# 1、进程和线程的区别
"""
进程：开销大，数据隔离，是能被系统最小的资源分配单位， cpython下能利用多核。
线程：开销小，数据共享，是能被CPU调用的最小单位，cpython下不能利用多核。
"""
# 2、进程池、线程池的优势和特点
"""
池节省了进程、线程的开启、关闭、切换的时间，减轻了操作系统调度的负担。
"""
# 3、线程和协程的异同?
"""
线程：切换需要操作系统，开销相对大，操作系统不可控，给操作系统的压力大
协程：切换需要python代码，开销相对小，用户操作可控，不给操作系统压力。
"""
# 4、请简述一下互斥锁和递归锁的异同？
"""
互斥锁在同一个线程中不能连续acquire
递归锁在同一个线程中可以连续acquire
"""
# 5、请列举一个python中数据安全的数据结构？
"""
Queue
"""
# 6、Python中如何使用线程池和进程池
"""
通过concurrent.futures模块导入
"""
# 7、简述 进程、线程、协程的区别 以及应用场景？
"""
进程：开销大，数据隔离，是能被系统最小的资源分配单位， cpython下能利用多核。
    高强度计算
线程：开销小，数据共享，是能被CPU调用的最小单位，cpython下不能利用多核。
    简单计算高并发
协程：切换需要python代码，开销最小，用户操作可控，不给操作系统压力。
    并发多且cpu资源不足。
"""
# 8、什么是并行，什么是并发？
"""
并行：两个程序，两个CPU，每个程序分别占用一个CPU。
并发：两个程序，一个CPU，每个程序交替的在一个CPU上执行。
"""
